// Dustin Escoffery
// Copyright 2010
#include "hook_winsock.h"
const int MAX_LOCAL_PLAYERS = 8;

int WINAPI MyConnect(SOCKET s, const struct sockaddr *name, int namelen)
{
   // Disable Battle.net
   return SOCKET_ERROR;
}

int WINAPI MyBind(SOCKET s, const struct sockaddr *name, int namelen)
{
   int ret;
   sockaddr_in* in = (sockaddr_in*)name;

   // Use next available pair of ports (6111, 6112), (6113, 6114)...
   while ((ret = bind(s, name, namelen)) != 0)
   {
      in->sin_port = htons(ntohs(in->sin_port) + 2);
   }
   return ret;
}

int WINAPI MySendTo(SOCKET s, const char *buf, int len, int flags, const struct sockaddr *to, int tolen)
{
   // Save
   int ret;
   sockaddr_in* in = (sockaddr_in*)to;
   USHORT port = in->sin_port;
   IN_ADDR addr = in->sin_addr;

   // Broadcast to additional ports
   if (in->sin_addr.s_addr == INADDR_BROADCAST)
   {
      short basePort = (ntohs(in->sin_port) & 1) ? 6111 : 6112;
      for (int i = 0; i < MAX_LOCAL_PLAYERS; i++)
      {
         in->sin_port = htons(basePort + i * 2);
         ret = sendto(s, buf, len, flags, to, tolen);
         // If offline, send to localhost
         if (ret == SOCKET_ERROR)
         {
            in->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
            ret = sendto(s, buf, len, flags, to, tolen);
         }
      }
   } else ret = sendto(s, buf, len, flags, to, tolen);

   // Restore
   in->sin_port = port;
   in->sin_addr = addr;
   return ret;
}
